//
//  WXQRScannerView.m
//  YLScaner
//
//  Created by Admin on 2025/9/25.
//

#import "WXQRScannerView.h"
@import AVFoundation;

@interface WXQRScannerView ()

// 摄像头预览层
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
// 半透明遮罩层（扫描框外区域）
@property (nonatomic, strong) UIView *maskLayer;
// 扫描框区域（冲击波活动范围）
@property (nonatomic, assign) CGRect scanFrame;
// 冲击波图层数组（多个同心圆）
@property (nonatomic, strong) NSMutableArray<CAShapeLayer *> *waveLayers;
// 波纹数量（建议3-4个，形成连续效果）
@property (nonatomic, assign) NSInteger waveCount;
// 单个波纹动画时长（秒）
@property (nonatomic, assign) CGFloat waveDuration;

@end

@implementation WXQRScannerView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setupConfig];
        [self setupPreviewLayer];
        [self setupMaskLayer];
        [self setupWaveLayers];
    }
    return self;
}

#pragma mark - 初始化配置
- (void)setupConfig {
    self.waveCount = 3; // 同时显示3个波纹
    self.waveDuration = 2.0; // 每个波纹动画持续2秒
    // 计算扫描框frame（居中，宽高240pt，可根据需求调整）
    CGFloat scanSize = 240;
    CGFloat screenWidth = self.bounds.size.width;
    CGFloat screenHeight = self.bounds.size.height;
    self.scanFrame = CGRectMake((screenWidth - scanSize)/2,
                                (screenHeight - scanSize)/2,
                                scanSize,
                                scanSize);
}

#pragma mark - 1. 设置摄像头预览层（基础扫描功能）
- (void)setupPreviewLayer {
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    // 配置摄像头输入（简化版，实际需加权限判断）
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    if ([session canAddInput:input]) {
        [session addInput:input];
    }
    // 配置元数据输出（二维码识别）
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    if ([session canAddOutput:output]) {
        [session addOutput:output];
    }
    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode]; // 只识别二维码
    
    // 创建预览层并添加到当前视图
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    self.previewLayer.frame = self.bounds;
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    [self.layer insertSublayer:self.previewLayer atIndex:0];
    
    // 启动会话（实际项目中需在主线程异步启动）
    [session startRunning];
}

#pragma mark - 2. 设置遮罩层（突出扫描框区域）
- (void)setupMaskLayer {
    // 1. 创建黑色半透明遮罩（覆盖整个屏幕）
    self.maskLayer = [[UIView alloc] initWithFrame:self.bounds];
    self.maskLayer.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6]; // 60%透明黑
    [self addSubview:self.maskLayer];
    
    // 2. 扫描框区域"挖空"（通过mask实现透明）
    UIView *scanBox = [[UIView alloc] initWithFrame:self.scanFrame];
    scanBox.backgroundColor = [UIColor clearColor];
    // 遮罩层的mask：scanBox的不透明区域会显示下层内容（即扫描框区域透明）
    self.maskLayer.maskView = scanBox;
}

#pragma mark - 3. 创建冲击波图层（核心动画载体）
- (void)setupWaveLayers {
    self.waveLayers = [NSMutableArray arrayWithCapacity:self.waveCount];
    for (int i = 0; i < self.waveCount; i++) {
        CAShapeLayer *waveLayer = [self createSingleWaveLayer];
        [self.maskLayer.layer addSublayer:waveLayer]; // 波纹添加到遮罩层上
        [self.waveLayers addObject:waveLayer];
    }
}

// 创建单个波纹图层（圆形，描边样式）
- (CAShapeLayer *)createSingleWaveLayer {
    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.frame = self.scanFrame; // 限制在扫描框内
    layer.fillColor = [UIColor clearColor].CGColor; // 填充透明
    layer.strokeColor = [UIColor colorWithRed:0.2 green:0.8 blue:0.3 alpha:1.0].CGColor; // 微信风格淡绿色
    layer.lineWidth = 1.5; // 波纹线宽
    layer.opacity = 0; // 初始透明（动画开始时显示）
    return layer;
}

#pragma mark - 4. 启动冲击波动画（核心逻辑）
- (void)startScanAnimation {
    // 停止所有现有动画
    [self stopScanAnimation];
    
    // 多个波纹按时间差启动（形成连续扩散效果）
    for (int i = 0; i < self.waveCount; i++) {
        CAShapeLayer *layer = self.waveLayers[i];
        // 每个波纹延迟0.5秒启动（总延迟 = i * 0.5）
        CGFloat delay = i * 0.5;
        [self startSingleWaveAnimation:layer delay:delay];
    }
}

// 单个波纹的动画（缩放+透明度渐变）
- (void)startSingleWaveAnimation:(CAShapeLayer *)layer delay:(CGFloat)delay {
    // 1. 计算扫描框中心（波纹扩散的起点）
    CGPoint center = CGPointMake(CGRectGetMidX(self.scanFrame), CGRectGetMidY(self.scanFrame));
    CGFloat maxRadius = self.scanFrame.size.width / 2; // 最大半径（扫描框一半）
    
    // 2. 透明度动画：从1→0
    CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnim.fromValue = @(1.0);
    opacityAnim.toValue = @(0.0);
    
    // 3. 缩放动画：通过更新路径实现（半径从0→maxRadius）
    CABasicAnimation *pathAnim = [CABasicAnimation animationWithKeyPath:@"path"];
    pathAnim.fromValue = (__bridge id)[UIBezierPath bezierPathWithArcCenter:center radius:0 startAngle:0 endAngle:2*M_PI clockwise:YES].CGPath;
    pathAnim.toValue = (__bridge id)[UIBezierPath bezierPathWithArcCenter:center radius:maxRadius startAngle:0 endAngle:2*M_PI clockwise:YES].CGPath;
    
    // 4. 组合动画
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[opacityAnim, pathAnim];
    group.duration = self.waveDuration; // 动画时长
    group.beginTime = CACurrentMediaTime() + delay; // 延迟启动
    group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; // 匀速扩散
    group.repeatCount = INFINITY; // 无限重复
    [layer addAnimation:group forKey:@"waveAnimation"];
}

#pragma mark - 停止动画
- (void)stopScanAnimation {
    for (CAShapeLayer *layer in self.waveLayers) {
        [layer removeAllAnimations];
        layer.opacity = 0; // 重置透明度
    }
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate（二维码识别回调）
- (void)metadataOutput:(AVCaptureMetadataOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    if (metadataObjects.count > 0) {
        AVMetadataMachineReadableCodeObject *obj = metadataObjects.firstObject;
        if ([obj.type isEqualToString:AVMetadataObjectTypeQRCode]) {
            NSLog(@"扫描结果：%@", obj.stringValue);
            // 识别成功后可停止动画
            [self stopScanAnimation];
        }
    }
}

@end
